<template>
  <div class="ware-position-page">
    <el-container>
      <el-aside width="260px" class="shelf-aside">
        <el-card shadow="never" header="货架列表" style="height: 690px">
          <el-input
            v-model="shelfFilter"
            placeholder="搜索货架"
            clearable
            size="small"
            class="shelf-filter"
          />
          <el-tree
            :data="filteredShelfTree"
            node-key="id"
            highlight-current
            :expand-on-click-node="false"
            default-expand-all
            @node-click="handleShelfClick"
          >
            <template #default="{ data }">
              <span class="tree-node" :title="data.label">
                {{ data.label }}
              </span>
            </template>
          </el-tree>
        </el-card>
      </el-aside>
      <el-main class="content-main">
        <el-card shadow="never" class="search-card">
          <el-form :model="searchForm" :inline="true" label-width="80px">
            <el-form-item label="满仓状态">
              <el-select
                v-model="searchForm.positionState"
                placeholder="请选择"
                clearable
                style="width: 180px"
              >
                <el-option label="启用" :value="1" />
                <el-option label="停用" :value="2" />
              </el-select>
            </el-form-item>
            <el-form-item label="仓位状态">
              <el-select
                v-model="searchForm.isLock"
                placeholder="请选择"
                clearable
                style="width: 180px"
              >
                <el-option label="未锁定" :value="0" />
                <el-option label="锁定" :value="1" />
              </el-select>
            </el-form-item>
            <el-form-item label="仓位名称">
              <el-input
                v-model="searchForm.positionCode"
                placeholder="请输入仓位名称/编码"
                clearable
                style="width: 200px"
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="handleSearch">查询</el-button>
              <el-button @click="handleReset">重置</el-button>
            </el-form-item>
          </el-form>
        </el-card>

       

        <el-card shadow="never" class="table-card">
          <div class="table-actions">
            <el-button type="primary" @click="openAddDialog">添加</el-button>
            <el-button
              type="danger"
              plain
              :disabled="!hasSelection"
              @click="handleBatchDelete"
            >
              批量删除
            </el-button>
          </div>
          <el-table
            :data="tableData"
            height="340px"
            border
            stripe
            v-loading="loading"
            @selection-change="handleSelectionChange"
          >
            <el-table-column type="selection" width="50" fixed="left"/>
            <el-table-column type="index" label="序号" width="60" fixed="left"/>
            <el-table-column label="仓位名称" width="180" fixed="left">
              <template #default="{ row }">
                {{ formatPositionName(row) }}
              </template>
            </el-table-column>
            <el-table-column prop="positionCode" label="仓位编码" width="140" />
            <el-table-column label="满仓状态" width="100">
              <template #default="{ row }">
            <el-tag :type="getFullStateTagType(row.isWarehouseFull)">
              {{ row.isWarehouseFull == 1 ? '满仓' : '未满' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="是否锁定" width="100">
              <template #default="{ row }">
                <el-tag :type="row.isLock == 1 ? 'warning' : 'success'">
                  {{ row.isLock == 1 ? '锁定' : '未锁定' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="状态" width="100">
              <template #default="{ row }">
                <el-tag :type="row.positionState == 1 ? 'success' : 'info'">
                  {{ row.positionState == 1 ? '启用' : '停用' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="shelfName" label="所属货架" width="150" />
            <el-table-column prop="positionRow" label="排号" width="80" />
            <el-table-column prop="positionColumn" label="列号" width="80" />
            <el-table-column prop="positionLayer" label="层号" width="80" />
            <el-table-column prop="positionDepth" label="深度" width="80" />
            <el-table-column label="操作时间" width="150">
              <template #default="{ row }">
                {{ formatDate(row.updateTime || row.createrTime) }}
              </template>
            </el-table-column>
            <el-table-column label="操作人" width="120">
              <template #default="{ row }">
                {{ row.updater || row.createor || '-' }}
              </template>
            </el-table-column>
            <el-table-column prop="positionDesc" label="备注" min-width="160" />
            <el-table-column label="操作" width="200" fixed="right">
              <template #default="{ row }">
                <el-button link type="primary" size="small" @click="openEditDialog(row)">编辑</el-button>
                <el-button link type="info" size="small" @click="openViewDialog(row)">查看</el-button>
                <el-button link type="danger" size="small" @click="handleDelete(row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>

        <el-card style="margin-top: 10px;">
          <div class="demonstration" style="margin-left: 200px;">
          <el-pagination
            v-model:current-page="pageinfo.pageIndex"
            v-model:page-size="pageinfo.pageSize"
            :page-sizes="[10, 20, 30, 50]"
            layout="total, sizes, prev, pager, next, jumper"
            :total="pageinfo.total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
        </el-card>

        <el-dialog
          v-model="addDialogVisible"
          :title="dialogTitle"
          width="720px"
          :close-on-click-modal="false"
        >
          <el-form
            ref="addFormRef"
            :model="addForm"
            :rules="addRules"
            label-width="90px"
          >
            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="仓位名称">
                  <el-input :value="positionNameDisplay" readonly placeholder="根据排/列/层/深自动生成" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="仓位编码">
                  <el-input
                    v-model="addForm.positionCode"
                    readonly
                    placeholder="请点击自动生成"
                    :disabled="isViewMode"
                  >
                    <template #append>
                      <el-button
                        @click="generatePositionCode"
                        :loading="generatingPositionCode"
                        :disabled="dialogMode !== 'add' || isViewMode"
                      >
                        自动生成
                      </el-button>
                    </template>
                  </el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="所属货架" prop="shelfId">
                  <el-select
                    v-model="addForm.shelfId"
                    placeholder="请选择"
                    clearable
                    filterable
                    style="width: 100%"
                    :loading="shelfOptionsLoading"
                    :disabled="isViewMode"
                  >
                    <el-option
                      v-for="item in shelfSelectOptions"
                      :key="item.shelfId"
                      :label="item.shelfName"
                      :value="item.shelfId"
                    />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="排号" prop="positionRow">
                  <el-input-number
                    v-model="addForm.positionRow"
                    :min="1"
                    :controls="false"
                    placeholder="请输入排号"
                    style="width: 100%"
                    :disabled="isViewMode"
                  />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="列号" prop="positionColumn">
                  <el-input-number
                    v-model="addForm.positionColumn"
                    :min="1"
                    :controls="false"
                    placeholder="请输入列号"
                    style="width: 100%"
                    :disabled="isViewMode"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="层号" prop="positionLayer">
                  <el-input-number
                    v-model="addForm.positionLayer"
                    :min="1"
                    :controls="false"
                    placeholder="请输入层号"
                    style="width: 100%"
                    :disabled="isViewMode"
                  />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="深度" prop="positionDepth">
                  <el-select
                    v-model="addForm.positionDepth"
                    placeholder="请选择深度"
                    :disabled="depthOptions.length === 0 || isViewMode"
                    style="width: 100%"
                  >
                    <el-option
                      v-for="item in availableDepthOptions"
                      :key="item.value"
                      :label="`${item.value} 深度`"
                      :value="item.value"
                      :disabled="item.disabled"
                    />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="是否最深" prop="isDepth">
                  <el-radio-group v-model="addForm.isDepth" :disabled="isViewMode">
                    <el-radio :value="0">否</el-radio>
                    <el-radio :value="1">是</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
            </el-row>

            <el-row v-if="depthUnavailable" style="margin-bottom: 12px">
              <el-col :span="24">
                <el-alert
                  type="warning"
                  title="该货架的所有深度已被占用，无法继续新增仓位"
                  :closable="false"
                  show-icon
                />
              </el-col>
            </el-row>

            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="仓位高度" prop="positionHeightId">
                  <el-radio-group v-model="addForm.positionHeightId" :disabled="isViewMode">
                    <el-radio
                      v-for="item in positionHeightOptions"
                      :key="item.value"
                      :value="item.value"
                    >
                      {{ item.label }}
                    </el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="状态" prop="positionState">
                  <el-radio-group v-model="addForm.positionState" :disabled="isViewMode">
                    <el-radio :value="1">启用</el-radio>
                    <el-radio :value="2">停用</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="是否锁定" prop="isLock">
                  <el-radio-group v-model="addForm.isLock" :disabled="isViewMode">
                    <el-radio :value="0">否</el-radio>
                    <el-radio :value="1">是</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="备注">
                  <el-input
                    v-model="addForm.positionDesc"
                    placeholder="请输入备注"
                    maxlength="200"
                    type="textarea"
                    :rows="2"
                    show-word-limit
                    :disabled="isViewMode"
                  />
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
          <template #footer>
            <div class="dialog-footer">
              <el-button @click="addDialogVisible = false">{{ isViewMode ? '关闭' : '取消' }}</el-button>
              <el-button v-if="!isViewMode" type="primary" :loading="addLoading" @click="handleSubmit">确定</el-button>
            </div>
          </template>
        </el-dialog>
      </el-main>
    </el-container>
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
import dayjs from 'dayjs'
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
import myaxios from '@/http/MyAxios'

type WarePosition = {
  positionId: number
  positionCode: string
  shelfId: number
  shelfName: string
  positionRow: number
  positionColumn: number
  positionLayer: number
  positionDepth: number
  isDepth: number
  positionHeightId?: number
  positionState: number
  isLock: number
  positionDesc?: string
  createor?: string
  createrTime?: string
  updater?: string
  updateTime?: string
  positionFullState?: string
  isWarehouseFull?: number
}

const tableData = ref<WarePosition[]>([])
const loading = ref(false)

const pageinfo = reactive({
  pageIndex: 1,
  pageSize: 10,
  total: 0,
})

const searchForm = reactive({
  positionCode: '',
  positionState: null as number | null,
  isLock: null as number | null,
})

const selectedShelfId = ref<number | null>(null)

const addDialogVisible = ref(false)
const addLoading = ref(false)
const addFormRef = ref<FormInstance>()
const generatingPositionCode = ref(false)
const dialogMode = ref<'add' | 'edit' | 'view'>('add')
const currentPositionId = ref<number | null>(null)
const TIME_SEGMENT_ORDER = ['YYYY', 'YY', 'MM', 'DD', 'HH', 'MI', 'SS']
const pad = (num: number, len = 2) => `${num}`.padStart(len, '0')
const positionHeightOptions = ref<Array<{ label: string; value: number }>>([])
const positionHeightLoading = ref(false)

const addForm = reactive({
  positionCode: '',
  shelfId: null as number | null,
  positionRow: null as number | null,
  positionColumn: null as number | null,
  positionLayer: null as number | null,
  positionDepth: null as number | null,
  positionHeightId: null as number | null,
  isDepth: 0,
  positionState: 1,
  isLock: 0,
  positionDesc: '',
})

const addRules: FormRules = {
  shelfId: [{ required: true, message: '请选择货架', trigger: 'change' }],
  positionRow: [{ required: true, message: '请输入排号', trigger: 'blur' }],
  positionColumn: [{ required: true, message: '请输入列号', trigger: 'blur' }],
  positionLayer: [{ required: true, message: '请输入层号', trigger: 'blur' }],
  positionDepth: [{ required: true, message: '请选择深度', trigger: 'change' }],
  positionHeightId: [{ required: true, message: '请选择高度', trigger: 'change' }],
  isDepth: [{ required: true, message: '请选择是否最深', trigger: 'change' }],
  positionState: [{ required: true, message: '请选择状态', trigger: 'change' }],
  isLock: [{ required: true, message: '请选择锁定状态', trigger: 'change' }],
}

const depthOptions = ref<number[]>([])
const usedDepths = ref<number[]>([])
const shelfSelectOptions = ref<Array<{ shelfId: number; shelfName: string; shelfDepthValue: number }>>([])
const shelfOptionsLoading = ref(false)
const selectedRows = ref<WarePosition[]>([])
const suppressDepthReset = ref(false)

const dialogTitle = computed(() => {
  if (dialogMode.value === 'edit') return '编辑仓位'
  if (dialogMode.value === 'view') return '查看仓位'
  return '添加仓位'
})
const isViewMode = computed(() => dialogMode.value === 'view')
const positionNameDisplay = computed(() => {
  const parts: string[] = []
  if (addForm.positionRow) parts.push(`${addForm.positionRow}排`)
  if (addForm.positionColumn) parts.push(`${addForm.positionColumn}列`)
  if (addForm.positionLayer) parts.push(`${addForm.positionLayer}层`)
  if (addForm.positionDepth) parts.push(`${addForm.positionDepth}深`)
  return parts.length ? parts.join('') + '位' : ''
})

const availableDepthOptions = computed(() =>
  depthOptions.value.map(value => ({
    value,
    disabled: usedDepths.value.includes(value) && value !== addForm.positionDepth,
  }))
)

const hasSelection = computed(() => selectedRows.value.length > 0)

const depthUnavailable = computed(
  () => depthOptions.value.length > 0 && availableDepthOptions.value.every(item => item.disabled)
)

const formatDate = (val?: string | Date | null) => {
  if (!val) return '-'
  return dayjs(val).format('YYYY-MM-DD')
}

const formatPositionName = (row: WarePosition) => {
  return `${row.positionRow ?? '-'}排${row.positionColumn ?? '-'}列${row.positionLayer ?? '-'}层${row.positionDepth ?? '-'}深`
}

const getFullStateTagType = (isFull?: number | null) => {
  if (isFull === 1) return 'success'
  return 'warning'
}

const getWarePositionList = () => {
  loading.value = true
  myaxios({
    url: '/api/WarePosition/GetWarePositionPage',
    method: 'get',
    params: {
      Pageindex: pageinfo.pageIndex,
      PageSize: pageinfo.pageSize,
      shelfId: selectedShelfId.value || undefined,
      positionCode: searchForm.positionCode || undefined,
      positionState: searchForm.positionState || undefined,
      isLock: searchForm.isLock || undefined,
    },
  })
    .then(res => {
      const data = res.data?.data
      tableData.value = data?.data || []
      pageinfo.total = data?.listCount || 0
      selectedRows.value = []
    })
    .catch(err => {
      console.error('获取仓位列表失败:', err)
      ElMessage.error('获取仓位列表失败')
    })
    .finally(() => {
      loading.value = false
    })
}

const handleSearch = () => {
  pageinfo.pageIndex = 1
  getWarePositionList()
}

const handleReset = () => {
  searchForm.positionCode = ''
  searchForm.positionState = null
  searchForm.isLock = null
  pageinfo.pageIndex = 1
  getWarePositionList()
}

const handleSizeChange = (val: number) => {
  pageinfo.pageSize = val
  pageinfo.pageIndex = 1
  getWarePositionList()
}

const handleCurrentChange = (val: number) => {
  pageinfo.pageIndex = val
  getWarePositionList()
}

const resetAddForm = () => {
  suppressDepthReset.value = false
  addForm.positionCode = ''
  addForm.shelfId = null
  addForm.positionRow = null
  addForm.positionColumn = null
  addForm.positionLayer = null
  addForm.positionDepth = null
  const defaultHeight = positionHeightOptions.value[0]?.value ?? null
  addForm.positionHeightId = defaultHeight
  addForm.isDepth = 0
  addForm.positionState = 1
  addForm.isLock = 0
  addForm.positionDesc = ''
  depthOptions.value = []
  usedDepths.value = []
  addFormRef.value?.clearValidate()
}

const ensureShelfOptions = async () => {
  if (!shelfSelectOptions.value.length) {
    await loadShelfTree()
  }
}

const openAddDialog = async () => {
  dialogMode.value = 'add'
  currentPositionId.value = null
  await ensureShelfOptions()
  if (!shelfSelectOptions.value.length) {
    ElMessage.warning('暂无可用货架，请先创建货架')
    return
  }
  resetAddForm()
  addDialogVisible.value = true
}

const loadUsedDepths = async (
  shelfId: number,
  positionRow?: number | null,
  positionColumn?: number | null,
  positionLayer?: number | null
) => {
  try {
    const params: any = {
      Pageindex: 1,
      PageSize: 1000,
      shelfId,
    }
    const res = await myaxios({
      url: '/api/WarePosition/GetWarePositionPage',
      method: 'get',
      params,
    })
    const list = res.data?.data?.data || []
    let filteredList = list
    // 如果指定了排/列/层，过滤出该位置的仓位
    if (positionRow && positionColumn && positionLayer) {
      filteredList = list.filter(
        (item: any) =>
          item.positionRow === positionRow &&
          item.positionColumn === positionColumn &&
          item.positionLayer === positionLayer
      )
    }
    const depths = filteredList
      .map((item: any) => Number(item.positionDepth))
      .filter((d: number) => Number.isFinite(d) && d > 0)
    usedDepths.value = Array.from(new Set(depths)) as number[]
  } catch (error) {
    console.error('获取该位置的仓位深度失败:', error)
    usedDepths.value = []
  }
}

watch(
  () => addForm.shelfId,
  async newShelfId => {
    depthOptions.value = []
    usedDepths.value = []
    if (!suppressDepthReset.value) {
      addForm.positionDepth = null
    }
    if (!newShelfId) return
    const shelf = shelfSelectOptions.value.find(item => item.shelfId === newShelfId)
    const depthValue = shelf?.shelfDepthValue || 1
    // 生成从最大深度到1的选项数组，例如深度为3时生成 [3, 2, 1]
    depthOptions.value = Array.from({ length: depthValue }, (_, idx) => depthValue - idx)
    // 如果已选择排/列/层，加载该位置的已使用深度
    if (addForm.positionRow && addForm.positionColumn && addForm.positionLayer) {
      await loadUsedDepths(newShelfId, addForm.positionRow, addForm.positionColumn, addForm.positionLayer)
    }
  }
)

// 当排/列/层变化时，重新加载已使用的深度
watch(
  [() => addForm.positionRow, () => addForm.positionColumn, () => addForm.positionLayer],
  async (values: Array<number | null>) => {
    const [row, col, layer] = values
    if (!addForm.shelfId || !row || !col || !layer) {
      usedDepths.value = []
      return
    }
    await loadUsedDepths(addForm.shelfId, row, col, layer)
  }
)

const handleSelectionChange = (rows: WarePosition[]) => {
  selectedRows.value = rows
}

const deleteWarePositions = async (positionIds: number[], isBatch = false) => {
  if (!positionIds.length) return
  const url = isBatch ? '/api/WarePosition/BatchDeleteWarePosition' : '/api/WarePosition/DeleteWarePosition'
  const payload = isBatch ? { positionIds } : { positionId: positionIds[0] }
  const res = await myaxios({
    url,
    method: 'post',
    data: payload,
  })
  if (res.data?.code !== 200) {
    throw new Error(res.data?.message || '删除仓位失败')
  }
  ElMessage.success(res.data?.message || '删除仓位成功')
  selectedRows.value = []
  getWarePositionList()
}

const handleDelete = async (row: WarePosition) => {
  if (!row?.positionId) return
  try {
    await ElMessageBox.confirm('确认删除该仓位吗？', '提示', { type: 'warning' })
    await deleteWarePositions([row.positionId])
  } catch (error: any) {
    if (error === 'cancel' || error === 'close') return
    const msg = error?.response?.data?.message || error?.message || '删除仓位失败'
    ElMessage.error(msg)
  }
}

const handleBatchDelete = async () => {
  const ids = selectedRows.value.map(item => item.positionId).filter((id): id is number => Boolean(id))
  if (!ids.length) {
    ElMessage.warning('请先选择需要删除的仓位')
    return
  }
  try {
    await ElMessageBox.confirm(`确认删除选中的 ${ids.length} 个仓位吗？`, '提示', { type: 'warning' })
    await deleteWarePositions(ids, true)
  } catch (error: any) {
    if (error === 'cancel' || error === 'close') return
    const msg = error?.response?.data?.message || error?.message || '批量删除失败'
    ElMessage.error(msg)
  }
}

const fetchWarePositionDetail = async (positionId: number) => {
  try {
    const res = await myaxios({
      url: '/api/WarePosition/GetWarePositionDetail',
      method: 'get',
      params: { positionId },
    })
    if (res.data?.code === 200 && res.data?.data) {
      return res.data.data as WarePosition
    }
    throw new Error(res.data?.message || '获取仓位详情失败')
  } catch (error: any) {
    console.error('获取仓位详情失败:', error)
    const msg = error?.response?.data?.message || error?.message || '获取仓位详情失败'
    ElMessage.error(msg)
    return null
  }
}

const populateFormWithDetail = async (detail: WarePosition) => {
  suppressDepthReset.value = true
  addForm.positionCode = detail.positionCode || ''
  addForm.shelfId = detail.shelfId || null
  await nextTick()
  addForm.positionRow = detail.positionRow ?? null
  addForm.positionColumn = detail.positionColumn ?? null
  addForm.positionLayer = detail.positionLayer ?? null
  addForm.positionDepth = detail.positionDepth ?? null
  addForm.positionHeightId = detail.positionHeightId ?? null
  addForm.isDepth = detail.isDepth ?? 0
  addForm.positionState = detail.positionState ?? 1
  addForm.isLock = detail.isLock ?? 0
  addForm.positionDesc = detail.positionDesc || ''
  suppressDepthReset.value = false

  if (detail.shelfId && detail.positionRow && detail.positionColumn && detail.positionLayer) {
    await loadUsedDepths(detail.shelfId, detail.positionRow, detail.positionColumn, detail.positionLayer)
  } else {
    usedDepths.value = []
  }
}

const openPositionDetailDialog = async (mode: 'edit' | 'view', row: WarePosition) => {
  if (!row?.positionId) {
    ElMessage.warning('缺少仓位ID')
    return
  }
  await ensureShelfOptions()
  const detail = await fetchWarePositionDetail(row.positionId)
  if (!detail) return
  dialogMode.value = mode
  currentPositionId.value = detail.positionId
  await populateFormWithDetail(detail)
  addDialogVisible.value = true
}

const openEditDialog = (row: WarePosition) => {
  openPositionDetailDialog('edit', row)
}

const openViewDialog = (row: WarePosition) => {
  openPositionDetailDialog('view', row)
}

watch(
  () => addDialogVisible.value,
  val => {
    if (!val) {
      addFormRef.value?.clearValidate()
      dialogMode.value = 'add'
      currentPositionId.value = null
      suppressDepthReset.value = false
    }
  }
)

const generatePositionCode = async () => {
  if (generatingPositionCode.value) return
  generatingPositionCode.value = true
  try {
    const res = await myaxios.get('/api/Number/GenerateNumber', {
      params: { targetCode: 'WarePosition', targetName: '仓位' },
    })
    if (res?.data?.code === 200 && res?.data?.data) {
      addForm.positionCode = String(res.data.data)
      ElMessage.success('编号生成成功')
      return true
    }
    throw new Error(res?.data?.message || '生成编号失败')
  } catch (error: any) {
    console.error('自动生成仓位编号失败，尝试根据规则生成:', error)
    try {
      const ruleRes = await myaxios({
        url: '/api/Number/QueryNumberingRules',
        method: 'get',
        params: { targetCode: 'WarePosition', targetName: '仓位' },
      })
      const rule = Array.isArray(ruleRes?.data?.data) ? ruleRes.data.data[0] : null
      if (!rule) {
        throw new Error(ruleRes?.data?.message || '未配置仓位编号规则')
      }
      const now = new Date()
      const segments = (rule.timeRule || '')
        .split(',')
        .map((s: string) => s.trim().toUpperCase())
        .filter(Boolean)
        .sort((a: string, b: string) => {
          const idxA = TIME_SEGMENT_ORDER.indexOf(a)
          const idxB = TIME_SEGMENT_ORDER.indexOf(b)
          if (idxA === -1 && idxB === -1) return 0
          if (idxA === -1) return 1
          if (idxB === -1) return -1
          return idxA - idxB
        })
      const datePart = segments
        .map((seg: string) => {
          switch (seg) {
            case 'YYYY':
              return String(now.getFullYear())
            case 'YY':
              return String(now.getFullYear()).slice(-2)
            case 'MM':
              return pad(now.getMonth() + 1)
            case 'DD':
              return pad(now.getDate())
            case 'HH':
              return pad(now.getHours())
            case 'MI':
              return pad(now.getMinutes())
            case 'SS':
              return pad(now.getSeconds())
            default:
              return ''
          }
        })
        .join('')
      const serialLength = Number(rule.serialLength || 3)
      const serial = '1'.padStart(serialLength > 0 ? serialLength : 3, '0')
      addForm.positionCode = `${rule.codePrefix || ''}${datePart}${serial}`
      ElMessage.success('依据编码规则生成成功')
      return true
    } catch (fallbackError: any) {
      console.error('根据编码规则生成仓位编号失败:', fallbackError)
      ElMessage.error(fallbackError?.message || '生成编号失败，请联系管理员')
      return false
    }
  } finally {
    generatingPositionCode.value = false
  }
}

const handleSubmit = async () => {
  if (dialogMode.value === 'view') {
    addDialogVisible.value = false
    return
  }
  if (depthUnavailable.value) {
    ElMessage.warning('当前货架所有深度均已使用，无法新增')
    return
  }
  if (!addFormRef.value) return
  const valid = await addFormRef.value.validate().catch(() => false)
  if (!valid) return

  if (!addForm.positionCode) {
    const success = await generatePositionCode()
    if (!success || !addForm.positionCode) {
      ElMessage.warning('请先生成仓位编号')
      return
    }
  }

  const payload = {
    positionCode: addForm.positionCode,
    shelfId: addForm.shelfId,
    positionRow: addForm.positionRow,
    positionColumn: addForm.positionColumn,
    positionLayer: addForm.positionLayer,
    positionDepth: addForm.positionDepth,
    positionHeightId: addForm.positionHeightId,
    isDepth: addForm.isDepth,
    positionState: addForm.positionState,
    isLock: addForm.isLock,
    positionDesc: addForm.positionDesc || '',
  }

  addLoading.value = true
  try {
    let res
    if (dialogMode.value === 'add') {
      res = await myaxios({
        url: '/api/WarePosition/CreateWarePosition',
        method: 'post',
        data: payload,
      })
    } else {
      if (!currentPositionId.value) {
        ElMessage.error('缺少仓位ID，无法保存')
        return
      }
      res = await myaxios({
        url: '/api/WarePosition/UpdateWarePosition',
        method: 'put',
        params: { positionId: currentPositionId.value },
        data: payload,
      })
    }

    if (res.data?.code === 200) {
      ElMessage.success(res.data?.message || (dialogMode.value === 'add' ? '新增仓位成功' : '更新仓位成功'))
      addDialogVisible.value = false
      getWarePositionList()
    } else {
      ElMessage.error(res.data?.message || (dialogMode.value === 'add' ? '新增仓位失败' : '更新仓位失败'))
    }
  } catch (error: any) {
    console.error(`${dialogMode.value === 'add' ? '新增' : '更新'}仓位失败:`, error)
    const msg =
      error?.response?.data?.message ||
      error?.message ||
      `${dialogMode.value === 'add' ? '新增' : '更新'}仓位失败，请稍后重试`
    ElMessage.error(msg)
  } finally {
    addLoading.value = false
  }
}

/**
 * 左侧货架
 */
type ShelfTreeNode = {
  id: number | string
  label: string
  children?: ShelfTreeNode[]
  shelfId?: number
}

const shelfTree = ref<ShelfTreeNode[]>([])
const shelfFilter = ref('')
const filteredShelfTree = computed(() => {
  const keyword = shelfFilter.value.trim().toLowerCase()
  if (!keyword) return shelfTree.value
  const filterNodes = (nodes: ShelfTreeNode[]): ShelfTreeNode[] => {
    const result: ShelfTreeNode[] = []
    nodes.forEach(node => {
      const match = node.label.toLowerCase().includes(keyword)
      if (match) {
        result.push(node)
      } else if (node.children?.length) {
        const children = filterNodes(node.children)
        if (children.length) {
          result.push({ ...node, children })
        }
      }
    })
    return result
  }
  return filterNodes(shelfTree.value)
})

const CHINESE_NUMBER_MAP: Record<string, number> = {
  单: 1,
  一: 1,
  二: 2,
  两: 2,
  双: 2,
  三: 3,
  四: 4,
  五: 5,
  六: 6,
  七: 7,
  八: 8,
  九: 9,
  十: 10,
}

const resolveShelfDepthValue = (item: any) => {
  // 优先使用后端返回的数字字段（兼容大小写）
  const depthValue = item?.shelfDepthValue ?? item?.ShelfDepthValue
  if (typeof depthValue === 'number' && depthValue > 0) {
    return depthValue
  }
  // 如果数字字段不存在，尝试从文本字段解析
  const depthText = String(item?.shelfDepth || item?.ShelfDepth || '')
  const numericMatch = depthText.match(/\d+/)
  if (numericMatch) {
    const num = Number(numericMatch[0])
    if (num > 0) return num
  }
  // 最后尝试中文数字映射
  const hit = Object.entries(CHINESE_NUMBER_MAP).find(([key]) => depthText.includes(key))
  return hit ? hit[1] : 1
}

const buildShelfTree = (shelves: any[]) => {
  shelfSelectOptions.value = shelves.map((item: any) => ({
    shelfId: item.shelfId,
    shelfName: item.shelfName || `货架${item.shelfId}`,
    shelfDepthValue: resolveShelfDepthValue(item),
  }))
  const groupMap: Record<string, ShelfTreeNode> = {}
  shelves.forEach(item => {
    const warehouseName = item.warehouseName || '未分配仓库'
    if (!groupMap[warehouseName]) {
      groupMap[warehouseName] = {
        id: `warehouse-${warehouseName}`,
        label: warehouseName,
        children: [],
      }
    }
    groupMap[warehouseName].children!.push({
      id: item.shelfId,
      label: item.shelfName || `货架${item.shelfId}`,
      shelfId: item.shelfId,
    })
  })
  shelfTree.value = Object.values(groupMap)
}

const isRootDictionary = (item: any) =>
  !item?.dictionaryParentId ||
  Number(item.dictionaryParentId) === 0 ||
  item.dictionaryParentId === '0'

const findDictionaryParentIdByName = async (name: string) => {
  try {
    const res = await myaxios.get('/api/Dictionary/GetDictionaryList', {
      params: { DictionaryName: name, Pageindex: 1, PageSize: 500 },
    })
    const list = res.data?.data?.data || []
    const target = list.find((item: any) => isRootDictionary(item) && (item.dictionaryName || '').includes(name))
    if (target?.dictionaryId) return target.dictionaryId
  } catch (error) {
    console.error(`按名称 ${name} 查询字典失败:`, error)
  }
  return null
}

const fetchDictionaryChildren = async (parentId: number | string | null) => {
  if (!parentId) return []
  try {
    const res = await myaxios.get('/api/Dictionary/GetDictionaryChildren', {
      params: { ParentId: parentId, Pageindex: 1, PageSize: 1000 },
    })
    return res.data?.data?.data || []
  } catch (error) {
    console.error('加载字典子项失败:', error)
    return []
  }
}

const loadPositionHeightOptions = async () => {
  if (positionHeightLoading.value) return
  positionHeightLoading.value = true
  try {
    const parentId = await findDictionaryParentIdByName('仓位高度')
    if (!parentId) {
      ElMessage.warning('未找到仓位高度字典，请先配置字典数据')
      positionHeightOptions.value = []
      return
    }
    const children = await fetchDictionaryChildren(parentId)
    positionHeightOptions.value = children.map((item: any) => ({
      label: item.dictionaryName || item.dictionaryCode || `高度${item.dictionaryId}`,
      value: Number(item.dictionaryId),
    }))
  } catch (error) {
    console.error('加载仓位高度字典失败:', error)
    ElMessage.error('加载仓位高度数据失败')
    positionHeightOptions.value = []
  } finally {
    positionHeightLoading.value = false
  }
}

const loadShelfTree = async () => {
  shelfOptionsLoading.value = true
  try {
    const res = await myaxios({
      url: '/api/Shelf/GetShelfPage',
      method: 'get',
      params: {
        Pageindex: 1,
        PageSize: 1000,
      },
    })
    const list = res.data?.data?.data || []
    buildShelfTree(list)
  } catch (error) {
    console.error('加载货架树失败:', error)
    ElMessage.error('加载货架列表失败')
  } finally {
    shelfOptionsLoading.value = false
  }
}

const handleShelfClick = (node: ShelfTreeNode) => {
  if (node.shelfId) {
    selectedShelfId.value = node.shelfId
    pageinfo.pageIndex = 1
    getWarePositionList()
  }
}

watch(
  () => positionHeightOptions.value,
  options => {
    if (!options.length) {
      addForm.positionHeightId = null
      return
    }
    const firstOption = options[0]
    if (!options.some(option => option.value === addForm.positionHeightId) && firstOption) {
      addForm.positionHeightId = firstOption.value
    }
  },
  { immediate: true }
)

onMounted(() => {
  loadShelfTree()
  getWarePositionList()
  loadPositionHeightOptions()
})
</script>

<style scoped>
.ware-position-page {
  padding: 10px;
}

.shelf-aside {
  padding-right: 10px;
}

.shelf-filter {
  margin-bottom: 10px;
}

.tree-node {
  display: inline-block;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.content-main {
  padding-left: 10px;
  display: flex;
  flex-direction: column;
}

.search-card,
.table-card {
  margin-bottom: 12px;
}

.table-actions {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
}

.action-row {
  margin-bottom: 12px;
}

.pagination-wrapper {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
  padding-bottom: 10px;
}
</style>

